#include "stdafx.h"

#include<stdio.h>
#include<stdlib.h>
#include <math.h>

#include"ppm.h"

TPPM::TPPM(void) {
    Colorized = false;
    GrigLines = false;
    ReCreate = false;
    Zoom = 1;
}

TPPM::~TPPM(void) {
    
}

int TPPM::GetColorF(float f) {
    float v = (f + 1.0f) / 2.0f;
	return (int)(v * 255);
}

float TPPM::GetFColor(int RorGorB) {
    float v = 1.0f * RorGorB / 255;
    return v * 2.0f - 1.0f;
}

int TPPM::SaveAsPPM(const char* fname, float* pY, int row, int col) {
	int R,G,B, grayScale;
	if (true == Colorized) {
		B = GetColorF(*pY);
		pY++;
		G = GetColorF(*pY);
		pY++;
		R = GetColorF(*pY);
		pY++;
	}
	else {
		grayScale = GetColorF(*pY);
		pY++;
	}
	Color RefColor = (true == Colorized)
		? Color::FromArgb(255, R, G, B)
		: Color::FromArgb(255, grayScale, grayScale, grayScale);
    int counti = 0;
    int countj = 0;
    FILE* file_to_save = NULL;
	fopen_s(&file_to_save, fname,"w");
    if(file_to_save == NULL)
        return EXIT_FAILURE;
    fprintf_s(file_to_save,"P3\n");
    fprintf_s(file_to_save,"# Create by \"Assosiative memory\" program.\n");
    fprintf_s(file_to_save,"%i %i\n255\n",col*Zoom,row*Zoom);
    for(int i = 0; i < row*Zoom; i++) {
        for(int j = 0; j < col*Zoom; j++) {
            if((GrigLines)&&((countj == (Zoom-1))||(countj == 0)||
                            (counti == (Zoom-1))||(counti == 0)))
                R = G = B = (int)0x7f;
            else {
                R = RefColor.R;
                G = RefColor.G;
                B = RefColor.B;
            }
            fprintf_s(file_to_save,"%i\n%i\n%i\n",RefColor.R,RefColor.G,RefColor.B);
            countj++;
            if(countj == Zoom) {
	            if (true == Colorized) {
		            B = GetColorF(*pY);
		            pY++;
					G = GetColorF(*pY);
					pY++;
					R = GetColorF(*pY);
					pY++;
				}
				else {
					grayScale = GetColorF(*pY);
					pY++;
				}
				RefColor = (true == Colorized)
					? Color::FromArgb(255, R, G, B)
					: Color::FromArgb(255, grayScale, grayScale, grayScale);
                countj = 0;
            }
        }
        counti++;
        if(counti != Zoom) {
            pY -= col*3;
	            if (true == Colorized) {
		            B = GetColorF(*pY);
		            pY++;
					G = GetColorF(*pY);
					pY++;
					R = GetColorF(*pY);
					pY++;
				}
				else {
					grayScale = GetColorF(*pY);
					pY++;
				}
				RefColor = (true == Colorized)
					? Color::FromArgb(255, R, G, B)
					: Color::FromArgb(255, grayScale, grayScale, grayScale);
        } else
            counti = 0;
    }
    fclose(file_to_save);
    return EXIT_SUCCESS;
}

int TPPM::GetColRowPPM(char* fname, int* col, int* row) {
    char c;
    char p[2];
    int i = 0;
    FILE* file_open_from = NULL;
	fopen_s(&file_open_from, fname,"r");
    if(file_open_from == NULL)
        return EXIT_FAILURE;
    do {
        fscanf_s(file_open_from,"%c",&c);
        p[i++] = c;/*P3*/
    } while((c != '\n') && (i < 3));
    if((i != 3) || (p[0] != 'P') || (p[1] != '3')) {
        fclose(file_open_from);
        printf("You can only load from ASCI encoded PPM file (P3)\n");
        *col = *row = 0;
        return EXIT_FAILURE;
    }
    do {
        fscanf_s(file_open_from,"%c",&c); /*# Create by Assosiative memory program.\n*/
    } while(c != '\n');
    fscanf_s(file_open_from,"%i %i\n",&*col,&*row);
    fclose(file_open_from);
    return EXIT_SUCCESS;
}

int TPPM::GetColPPM(char* fname) {
	int col = 0;
	int row = 0;
	this->GetColRowPPM(fname, &col, &row);
	return col;
}

int TPPM::GetRowPPM(char* fname) {
	int col = 0;
	int row = 0;
	this->GetColRowPPM(fname, &col, &row);
	return row;
}

float TPPM::f(float s, int dl) {
    if(dl <= 0)
        dl = 1;
	double one_step = ((double)1.0)/((double)dl);
    if(s == 0.0)
        return (float)one_step;
    if(s > +1.0)
        return +1.0;
    if(s < -1.0)
        return -1.0;

    double step = ((double)s)/one_step;
	if (step > 0)
		return (float)(ceil(step) * one_step);
	if (step < 0)
		return (float)(floor(step) * one_step);
	return (float)(step * one_step);
}


int TPPM::LoadFromPPM(char* fname, float* pY, int srow, int scol) {
    int R,G,B,col,row,ibuff;
    char c;
    char p[2];
    int i = 0;
    FILE* file_open_from = NULL;
	fopen_s(&file_open_from, fname,"r");
    if(file_open_from == NULL)
        return EXIT_FAILURE;    
    do {
        fscanf_s(file_open_from,"%c",&c);
        p[i++] = c;/*P3*/
    } while((c != '\n') && (i < 3));
    if((i != 3) || (p[0] != 'P') || (p[1] != '3')) {
        fclose(file_open_from);
        printf("You can only load from ASCI encoded PPM file (P3)");
        return EXIT_FAILURE;
    }
    do {
        fscanf_s(file_open_from,"%c",&c); /*# Create by Assosiative memory program.\n*/
    } while(c != '\n');
    fscanf_s(file_open_from,"%i %i\n",&col,&row);
    fscanf_s(file_open_from,"%i\n",&ibuff);     //255
    if((col != scol) && (row != srow))
        printf("Size (%ix%i) is difrent then (%ix%i) !\n",col,row,scol,srow);
    else
        for(int i = 0; i < row; i++) {
            for(int j = 0; j < col; j++) {
                fscanf_s(file_open_from,"%i\n%i\n%i\n",&R,&G,&B);
				if (true == Colorized) {
				    *pY = f(GetFColor(B), 255);
				    pY++;
				    *pY = f(GetFColor(G), 255);
				    pY++;
				    *pY = f(GetFColor(R), 255);
				    pY++;
				}
				else {
					int grayScale = (int)((0.3 * R) + (0.59 * G) + (0.11 * B));
					*pY = f(GetFColor(grayScale), 255);
					pY++;
				}
            }
            fscanf_s(file_open_from,"\n");
        }
    fclose(file_open_from);
    return EXIT_SUCCESS;
}
